package mts.messages;

import java.util.ArrayList;
import java.util.List;

import mts.common.CommonSettings;
import mts.constants.Direction;
import mts.constants.MessageType;
import mts.constants.StatusType;


public class StatusMessage extends Message {
	
	public static final int INDEX_CAR = Message.INDEX_MESSAGE_TYPE + 1;
	public static final int INDEX_CURRENT_FLOOR =  INDEX_CAR + 1;
	public static final int INDEX_DESTINATION_FLOOR = INDEX_CURRENT_FLOOR + 1;
	public static final int INDEX_STATUS = INDEX_DESTINATION_FLOOR + 1;
	public static final int INDEX_DIRECTION = INDEX_STATUS + 1;
	public static final int INDEX_CURRENT_HALL_CALLS = INDEX_DIRECTION + 1;
	
	public static final int MESSAGE_LENGTH = INDEX_CURRENT_HALL_CALLS + 1;

	private byte car;
	private byte currentFloor;
	private byte destinationFloor;
	private StatusType status = StatusType.ERROR;	
	private Direction direction;	
	private ArrayList<Byte> currentHallCalls = new ArrayList<Byte>(CommonSettings.NUMBER_OF_FLOORS);
	
	public byte getCar() {
		return car;
	}

	public byte getCurrentFloor() {
		return currentFloor;
	}

	public byte getDestinationFloor() {
		return destinationFloor;
	}

	public StatusType getStatus() {
		return status;
	}

	public Direction getDirection() {
		return direction;
	}
	
	public List<Byte> getCurrentHallCalls() {
		return currentHallCalls;
	}

	public StatusMessage(byte currentFloor, byte destinationFloor, StatusType status, Direction direction)
	{
		this();
		
		this.currentFloor = currentFloor;
		this.destinationFloor = destinationFloor;		
		this.status = status;
		this.direction = direction;
	}
	
//	@Deprecated
//	public StatusMessage(StatusMessage statusMessage) {
//		this();	
//		this.car = statusMessage.car;
//		this.currentFloor = statusMessage.currentFloor;
//		this.destinationFloor = statusMessage.destinationFloor;		
//		this.status = statusMessage.status;
//		this.direction = statusMessage.direction;
//		this.currentHallCalls = (ArrayList<Byte>)statusMessage.currentHallCalls.clone();
//	}
	
	private StatusMessage() {
		super(MessageType.STATUS_REPLY);
	}
	
	public static StatusMessage deserialize(byte[] data) {
		StatusMessage statusMessage = new StatusMessage();
		statusMessage.car = data[INDEX_CAR];
		statusMessage.currentFloor = data[INDEX_CURRENT_FLOOR];		
		statusMessage.destinationFloor = data[INDEX_DESTINATION_FLOOR];
		statusMessage.status = StatusType.valueOf(data[INDEX_STATUS]);
		statusMessage.direction = Direction.valueOf(data[INDEX_DIRECTION]);
	
		
		for (byte i = 0; i < CommonSettings.NUMBER_OF_FLOORS; i++) {
			int dataIndex = i + INDEX_CURRENT_HALL_CALLS;
			if (data[dataIndex] != 0) {
				statusMessage.currentHallCalls.add(i);
			}
		}
		
		return statusMessage;
	}
	
	public byte[] serialize() {
		byte[] data = new byte[MESSAGE_LENGTH];
		
		data[Message.INDEX_MESSAGE_TYPE] = getMessageType().getByteValue();
		data[INDEX_CURRENT_FLOOR] = currentFloor;
		data[INDEX_DESTINATION_FLOOR] = destinationFloor;
		data[INDEX_STATUS] = status.getByteValue();
		data[INDEX_DIRECTION] = direction.getByteValue();
		
		for (Byte floor: currentHallCalls) {
			int dataIndex = floor + INDEX_CURRENT_HALL_CALLS;
			data[dataIndex] = 1;
		}
				
		return data;
	}
	
	
	
	@Override
	public boolean equals(Object other) {
		if (!(other instanceof StatusMessage)) {
			return false;
		}
		
		StatusMessage o = (StatusMessage)other;
		
		return currentFloor == o.currentFloor &&
				destinationFloor == o.destinationFloor &&
				status == o.status &&
				direction == o.direction;
	}

	

	@Override
	public String toString() {
		return "StatusMessage [" +
		"messageType: " + getMessageType() + 
		", currentFloor: " + currentFloor +
		", destinationFloor: " + destinationFloor  +
		", status: " + status +
		", direction: " + direction +
		"]";
	}
	
	
	

}
